﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RhythmComet.Services;
using FMOD;
using RhythmComet.Utils;

namespace RhythmComet.Gameplay
{
#if !XBOX
    public class SpectrumAnalyzer : DrawableGameComponent
    {
        private RhythmCometGame game;
        private GraphicsDeviceManager graphics;
        private Camera camera;

        private Mp3Player player;

        private BasicEffect effect;
        private VertexPositionColor[] vertices;

        private Color barColor;
        private Vector3 position;
        private float barHeight;
        private float barWidth;
        private float barSpacing;
        private float zDepth;

        private float[] lastValues;
        private float[] smoothSpectrum;
        private float[] currentSpectrum;
        private int[] beginValues;
        private int[] endValues;

        public SpectrumAnalyzer(RhythmCometGame game) : base(game) 
        {
            this.game = game;
            this.graphics = game.Graphics;

            this.player = game.Player;

            this.camera = game.Camera;
        }

        public float[] CurrentSpectrum
        {
            get { return currentSpectrum; }
        }

        public float[] SmoothSpectrum
        {
            get { return smoothSpectrum; }
        }

        public override void Initialize()
        {
            beginValues = new int[6] { 0, 3, 6, 33, 76, 131 };
            endValues = new int[6] { 3, 6, 33, 76, 131, 256 };
            lastValues = new float[6] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
            smoothSpectrum = new float[6] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
            currentSpectrum = new float[6] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
            vertices = new VertexPositionColor[7 * 6];

            barColor = Color.Gray;
            barHeight = 500.0f;
            barWidth = 20.0f;
            barSpacing = 3.0f;
            zDepth = -1.0f;
            position = new Vector3(-ScreenHelper.HorizontalLimit, -ScreenHelper.VerticalLimit, 0.0f);

            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            player.SetSpectrum();

            for (int i = 0; i < 6; i++)
            {
                currentSpectrum[i] = 0.0f;
                smoothSpectrum[i] = 0.0f;
                for (int j = beginValues[i]; j < endValues[i]; j++)
                {
                    currentSpectrum[i] += player.Spectrum[j];
                }
                smoothSpectrum[i] = currentSpectrum[i];
                smoothSpectrum[i] = (0.7f * smoothSpectrum[i]) + (0.3f * lastValues[i]);
                lastValues[i] = smoothSpectrum[i];
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            //effect = new BasicEffect(GraphicsDevice, null);
            //effect.Projection = camera.Projection;
            //effect.View = camera.View;
            //effect.World = Matrix.Identity;

            //float begin = position.X;

            //for (int i = 0; i < 6; i++)
            //{
            //    int index = i * 6;
            //    float energyHeight = (smoothSpectrum[i] * barHeight) + position.Y;
            //    vertices[index].Position = new Vector3(begin, position.Y, zDepth);
            //    vertices[index + 1].Position = new Vector3(begin, energyHeight, zDepth);
            //    vertices[index + 2].Position = new Vector3(begin + barWidth, position.Y, zDepth);
            //    vertices[index + 3].Position = new Vector3(begin + barWidth, position.Y, zDepth);
            //    vertices[index + 4].Position = new Vector3(begin, energyHeight, zDepth);
            //    vertices[index + 5].Position = new Vector3(begin + barWidth, energyHeight, zDepth);

            //    begin = begin + barWidth + barSpacing;

            //    for (int j = index; j < index + 6; j++)
            //        vertices[j].Color = barColor;
            //}

            //effect.VertexColorEnabled = true;
            //effect.Begin();
            //foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            //{
            //    pass.Begin();
            //    graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
            //        vertices, 0, vertices.Length / 3);
            //    pass.End();
            //}
            base.Draw(gameTime);
        }
    }
#endif
}
